<template>
  <div class="back-button-container">
    <button class="back-button" @click="goBack">返回</button>
  </div>
  <div class="id-card-ocr-container">
    <!-- 错误提示 -->
    <div v-if="error" class="error-message">{{ error }}</div>

    <!-- 身份证正面上传区域 -->
    <div class="upload-section">
      <h3>身份证正面</h3>
      <div class="upload-area front">
        <div class="upload-box" @click="openFrontFileDialog">
          <!-- 未上传时显示占位图 -->
          <div class="placeholder" v-if="!frontImageUrl">
            <div class="id-card-frame">
              <div class="frame-top"></div>
              <div class="frame-middle">
                <i class="icon id-card-icon"></i>
                <p class="upload-text">点击上传身份证正面</p>
                <p class="hint-text">含人像面</p>
              </div>
              <div class="frame-bottom"></div>
            </div>
            <div class="plus-icon" @click.stop="openFrontFileDialog">+</div>
          </div>
          <!-- 已上传时显示预览图 -->
          <div class="preview-container" v-else>
            <img 
              :src="frontImageUrl" 
              alt="身份证正面预览" 
              class="preview-image"
              @load="handleImageLoad('front')"
              @error="handleImageError('front')"
            >
            <button class="remove-btn" @click.stop="removeFrontFile">×</button>
          </div>
          <input 
            type="file" 
            ref="frontFileInput" 
            class="file-input" 
            accept="image/*" 
            @change="handleFrontFileSelect"
          >
        </div>
      </div>
    </div>

    <!-- 身份证反面上传区域 -->
    <div class="upload-section">
      <h3>身份证反面</h3>
      <div class="upload-area back">
        <div class="upload-box" @click="openBackFileDialog">
          <!-- 未上传时显示占位图 -->
          <div class="placeholder" v-if="!backImageUrl">
            <div class="id-card-frame">
              <div class="frame-top"></div>
              <div class="frame-middle">
                <i class="icon id-card-icon"></i>
                <p class="upload-text">点击上传身份证反面</p>
                <p class="hint-text">含国徽面</p>
              </div>
              <div class="frame-bottom"></div>
            </div>
            <div class="plus-icon" @click.stop="openBackFileDialog">+</div>
          </div>
          <!-- 已上传时显示预览图 -->
          <div class="preview-container" v-else>
            <img 
              :src="backImageUrl" 
              alt="身份证反面预览" 
              class="preview-image"
              @load="handleImageLoad('back')"
              @error="handleImageError('back')"
            >
            <button class="remove-btn" @click.stop="removeBackFile">×</button>
          </div>
          <input 
            type="file" 
            ref="backFileInput" 
            class="file-input" 
            accept="image/*" 
            @change="handleBackFileSelect"
          >
        </div>
      </div>
    </div>

    <!-- 下一步按钮 -->
    <div class="next-button-container">
      <button class="next-button" @click="handleNext" :disabled="!frontFile ||!backFile || !isBackColorValid">下一步</button>
    </div>
  </div>

  <!-- 顶部轻提示 -->
  <div 
    v-if="showToast" 
    class="toast-container"
    :class="{ 'toast-visible': showToast }"
  >
    <div 
      class="toast"
      :class="['animate__animated', toastAnimation]"
    >
      {{ toastMessage }}
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref, onMounted, onUnmounted } from 'vue';
import { useRouter } from 'vue-router';
import Tesseract from 'tesseract.js';

// 状态管理
const frontFile = ref<File | null>(null);
const backFile = ref<File | null>(null);
const frontImageUrl = ref('');
const backImageUrl = ref('');
const error = ref('');
const frontFileInput = ref<HTMLInputElement | null>(null);
const backFileInput = ref<HTMLInputElement | null>(null);
const router = useRouter();

// 顶部轻提示相关状态
const showToast = ref(false);
const toastMessage = ref('');
const toastAnimation = ref('animate__fadeInDown');
let toastTimer: any;

// 目标颜色：#DC4041 (RGB: 220, 64, 65)
const DC4041_COLOR = { r: 220, g: 64, b: 65 };
// 颜色匹配容差范围
const COLOR_TOLERANCE = 40;
// 身份证反面验证状态
const isBackColorValid = ref(false);
// 用于模糊匹配的正则表达式（支持"中华人民"后接任意字符再到"国"，容错错别字）
const KEYWORD_REGEX = /中华人民.*国/; 

// 打开正面文件选择对话框
const openFrontFileDialog = () => {
  frontFileInput.value?.click();
};

// 打开反面文件选择对话框
const openBackFileDialog = () => {
  backFileInput.value?.click();
};

// 处理图片加载成功事件
const handleImageLoad = (type: 'front' | 'back') => {
  showToastMessage(`${type === 'front' ? '身份证正面' : '身份证反面'}图片加载成功`);
};

// 处理图片加载错误事件
const handleImageError = (type: 'front' | 'back') => {
  const message = `${type === 'front' ? '身份证正面' : '身份证反面'}图片加载失败`;
  console.error(message);
  error.value = message;
  showToastMessage(message);
};

// 颜色扫描：检测目标颜色是否存在
const checkColorExistence = (imageUrl: string, targetColor: {r: number, g: number, b: number}): Promise<boolean> => {
  return new Promise((resolve) => {
    const img = new Image();
    img.crossOrigin = 'anonymous';
    img.src = imageUrl;

    img.onload = () => {
      const canvas = document.createElement('canvas');
      const ctx = canvas.getContext('2d');
      if (!ctx) {
        const errMsg = '无法获取画布上下文，颜色检测失败';
        console.error(errMsg);
        showToastMessage(errMsg);
        resolve(false);
        return;
      }

      // 缩小图片尺寸以提高性能
      const scale = 0.5;
      const width = img.width * scale;
      const height = img.height * scale;
      canvas.width = width;
      canvas.height = height;
      ctx.drawImage(img, 0, 0, width, height);

      try {
        const imageData = ctx.getImageData(0, 0, width, height);
        const data = imageData.data;

        // 遍历像素
        for (let i = 0; i < data.length; i += 4) {
          const r = data[i];
          const g = data[i + 1];
          const b = data[i + 2];
          const a = data[i + 3];

          if (a < 100) continue; // 跳过透明度过高的像素

          // 判断是否接近目标颜色
          const colorMatch = 
            Math.abs(r - targetColor.r) <= COLOR_TOLERANCE &&
            Math.abs(g - targetColor.g) <= COLOR_TOLERANCE &&
            Math.abs(b - targetColor.b) <= COLOR_TOLERANCE;

          if (colorMatch) {
            resolve(true);
            return;
          }
        }
        resolve(false);
      } catch (err) {
        const errMsg = '颜色分析过程出错';
        console.error(errMsg, err);
        showToastMessage(errMsg);
        resolve(false);
      }
    };

    img.onerror = (err) => {
      const errMsg = '图片加载失败，无法进行颜色分析';
      console.error(errMsg, err);
      showToastMessage(errMsg);
      resolve(false);
    };
  });
};

// 显示轻提示
const showToastMessage = (message: string) => {
  // 清除现有提示
  if (toastTimer) clearTimeout(toastTimer);
  
  // 更新提示内容并显示
  toastMessage.value = message;
  showToast.value = true;
  toastAnimation.value = 'animate__fadeInDown';
  
  // 3秒后隐藏提示
  toastTimer = setTimeout(() => {
    hideToast();
  }, 3000);
};

// 隐藏轻提示
const hideToast = () => {
  toastAnimation.value = 'animate__fadeOutUp';
  setTimeout(() => {
    showToast.value = false;
  }, 300);
};

// 文件验证
const handleFileValidation = async (file: File, type: 'front' | 'back') => {
  error.value = '';
  try {
    // 基础验证：格式和大小
    if (!file.type.startsWith('image/')) {
      const errMsg = '请上传图片文件';
      error.value = errMsg;
      showToastMessage(errMsg);
      return;
    }
    if (file.size / 1024 / 1024 > 2) {
      const errMsg = '图片过大，请上传小于2MB的图片';
      error.value = errMsg;
      showToastMessage(errMsg);
      return;
    }

    // 创建图片URL
    const imageUrl = URL.createObjectURL(file);
    
    // 先设置图片URL以显示预览
    if (type === 'front') {
      frontImageUrl.value = imageUrl;
    } else {
      backImageUrl.value = imageUrl;
    }
    
    // 显示上传中提示
    showToastMessage(`${type === 'front' ? '身份证正面' : '身份证反面'}上传中...`);
    
    // OCR识别
    showToastMessage(`正在识别${type === 'front' ? '身份证正面' : '身份证反面'}文字...`);
    const { data: { text } } = await Tesseract.recognize(
      imageUrl,
      'eng+chi_sim',
      { 
        logger: m => {
          // 显示OCR进度
          if (m.status === 'recognizing text') {
            showToastMessage(`识别中...${Math.round(m.progress * 100)}%`);
          }
        }
      }
    );
    
    // 处理识别结果（移除空白字符，用于后续匹配）
    const processedText = text.replace(/\s+/g, '').trim();
    const finalText = processedText.replace(/([。！？])/g, '$1\n');
    console.log(`${type === 'front' ? '正面' : '反面'}OCR识别结果:\n`, finalText);
    showToastMessage(`${type === 'front' ? '身份证正面' : '身份证反面'}文字识别完成`);
    
    // 处理反面图片时按新逻辑验证
    if (type === 'back') {
      // 第一步：验证DC4041颜色是否存在
      showToastMessage('正在验证证件基础信息...');
      const isDC4041Exist = await checkColorExistence(imageUrl, DC4041_COLOR);
      
      if (!isDC4041Exist) {
        // 颜色不存在：提示重新上传真实证件
        showToastMessage('请重新上传真实证件');
        isBackColorValid.value = false;
        backFile.value = file;
        return;
      }
      
      // 第二步：颜色存在，使用正则表达式进行模糊匹配（容错错别字）
      showToastMessage('正在验证证件有效性...');
      // 匹配规则：包含"中华人民"且后面有"国"，中间允许任意字符（解决"其"代替"共"等错别字问题）
      const isKeywordExist = KEYWORD_REGEX.test(processedText);
      
      if (isKeywordExist) {
        // 符合模糊匹配规则：认证成功
        showToastMessage('证件认证成功');
        isBackColorValid.value = true;
      } else {
        // 不匹配：证件失效
        showToastMessage('证件失效重新上传');
        isBackColorValid.value = false;
      }
      
      backFile.value = file;
    } else {
      // 正面图片处理
      frontFile.value = file;
      showToastMessage('身份证正面上传成功');
    }
  } catch (err: any) {
    const errMsg = err.message || '上传失败，请重试';
    console.error('文件验证过程中出错:', err);
    error.value = errMsg;
    showToastMessage(errMsg);
    
    // 出错时清除图片预览
    if (type === 'front') {
      frontImageUrl.value = '';
    } else {
      backImageUrl.value = '';
    }
  }
};

// 处理正面文件选择
const handleFrontFileSelect = (e: Event) => {
  const files = (e.target as HTMLInputElement)?.files;
  if (files && files.length > 0) {
    if (frontFile.value) {
      removeFrontFile();
    }
    handleFileValidation(files[0], 'front');
  }
};

// 处理反面文件选择
const handleBackFileSelect = (e: Event) => {
  const files = (e.target as HTMLInputElement)?.files;
  if (files && files.length > 0) {
    if (backFile.value) {
      removeBackFile();
    }
    handleFileValidation(files[0], 'back');
  }
};

// 移除正面图片
const removeFrontFile = () => {
  if (frontImageUrl.value) {
    URL.revokeObjectURL(frontImageUrl.value);
    frontImageUrl.value = '';
    frontFile.value = null;
    showToastMessage('身份证正面已移除');
  }
};

// 移除反面图片
const removeBackFile = () => {
  if (backImageUrl.value) {
    URL.revokeObjectURL(backImageUrl.value);
    backImageUrl.value = '';
    backFile.value = null;
    isBackColorValid.value = false;
    showToastMessage('身份证反面已移除');
  }
};

// 下一步
const handleNext = () => {
  if (frontFile.value && backFile.value && isBackColorValid.value) {
    showToastMessage('正在跳转至下一步...');
    setTimeout(() => {
      router.push('/facet').catch(err => {
        const errMsg = '跳转失败，请重试';
        console.error(errMsg, err);
        error.value = errMsg;
        showToastMessage(errMsg);
      });
    }, 800);
  } else if (!isBackColorValid.value) {
    showToastMessage('请上传有效的身份证反面图片');
  } else {
    showToastMessage('请先完成身份证正反面上传');
  }
};

// 返回
const goBack = () => {
  showToastMessage('正在返回...');
  setTimeout(() => {
    router.push('/faceo').catch(err => {
      const errMsg = '返回失败，请重试';
      console.error(errMsg, err);
      error.value = errMsg;
      showToastMessage(errMsg);
    });
  }, 800);
};

// 组件卸载时清理资源
onUnmounted(() => {
  if (frontImageUrl.value) URL.revokeObjectURL(frontImageUrl.value);
  if (backImageUrl.value) URL.revokeObjectURL(backImageUrl.value);
  if (toastTimer) clearTimeout(toastTimer);
});

onMounted(() => {
  console.log('组件挂载完成');
  Tesseract.createWorker(null, 1, {
    logger: m => {
      console.log('Worker初始化:', m);
      if (m.status === 'loading tesseract core') {
        showToastMessage('正在初始化识别引擎...');
      }
    }
  }).then(worker => {
    worker.reinitialize()
      .then(() => worker.load('eng+chi_sim'))
      .then(() => {
        showToastMessage('识别引擎初始化完成');
        worker.terminate();
      })
      .catch(err => {
        const errMsg = '语言包加载失败，可能影响识别效果';
        console.error(errMsg, err);
        showToastMessage(errMsg);
      });
  }).catch(err => {
    const errMsg = '识别引擎初始化失败';
    console.error(errMsg, err);
    showToastMessage(errMsg);
  });
});
</script>

<style scoped>
/* 原有样式保持不变 */
.id-card-ocr-container {
  max-width: 600px;
  margin: 0 auto;
  padding: 20px;
}

.back-button-container {
  position: absolute;
  top: 10px;
  left: 10px;
  z-index: 100;
}

.back-button {
  padding: 5px 10px;
  background-color: #54EA8C;
  color: white;
  border: none;
  border-radius: 5px;
  cursor: pointer;
}

.upload-section {
  margin-top: 5vh;
}

.upload-section h3 {
  color: #333;
  margin-bottom: 10px;
  font-size: 18px;
}

.upload-area {
  border-radius: 8px;
  overflow: hidden;
}

.upload-area.front {
  border: 2px dashed #1e88e5;
}

.upload-area.back {
  border: 2px dashed #43a047;
}

.upload-box {
  position: relative;
  width: 100%;
  height: 220px;
  background-color: #f8f9fa;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: background-color 0.3s;
}

.upload-box:hover {
  background-color: #f0f7ff;
}

.placeholder {
  position: relative;
  width: 280px;
  height: 180px;
}

.id-card-frame {
  width: 100%;
  height: 100%;
  position: relative;
}

.frame-top {
  height: 20px;
  border-top: 1px solid #ccc;
  border-left: 1px solid #ccc;
  border-right: 1px solid #ccc;
  border-top-left-radius: 8px;
  border-top-right-radius: 8px;
}

.frame-middle {
  height: 140px;
  border-left: 1px solid #ccc;
  border-right: 1px solid #ccc;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
}

.frame-bottom {
  height: 20px;
  border-bottom: 1px solid #ccc;
  border-left: 1px solid #ccc;
  border-right: 1px solid #ccc;
  border-bottom-left-radius: 8px;
  border-bottom-right-radius: 8px;
}

.icon {
  font-size: 24px;
  margin-bottom: 10px;
}

.id-card-icon {
  color: #1e88e5;
}

.upload-text {
  color: #666;
  font-size: 15px;
  margin: 0 0 5px 0;
}

.hint-text {
  color: #999;
  font-size: 12px;
  margin: 0;
}

.plus-icon {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  width: 40px;
  height: 40px;
  background-color: rgba(255, 0, 0, 0.7);
  color: white;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 24px;
  cursor: pointer;
  z-index: 5;
  box-shadow: 0 2px 5px rgba(0,0,0,0.2);
}

.preview-container {
  position: relative;
  width: 100%;
  height: 100%;
}

.preview-image {
  width: 100%;
  height: 100%;
  object-fit: contain;
}

.remove-btn {
  position: absolute;
  top: 10px;
  right: 10px;
  width: 30px;
  height: 30px;
  background-color: rgba(255, 255, 255, 0.8);
  border: none;
  border-radius: 50%;
  color: #f44336;
  font-size: 20px;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  box-shadow: 0 1px 3px rgba(0,0,0,0.2);
}

.file-input {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  opacity: 0;
  cursor: pointer;
  z-index: 10;
}

.next-button-container {
  text-align: center;
  margin-top: 20px;
}

.next-button {
  padding: 10px 30px;
  background-color: #54EA8C;
  color: white;
  border: none;
  border-radius: 5px;
  font-size: 16px;
  cursor: pointer;
}

.next-button:disabled {
  background-color: #ccc;
  cursor: not-allowed;
}

.error-message {
  color: #f44336;
  margin: 15px 0;
  text-align: center;
  padding: 8px;
  border-radius: 4px;
}

/* 顶部轻提示样式 */
.toast-container {
  position: fixed;
  top: -50px;
  left: 50%;
  transform: translateX(-50%);
  width: 80%;
  max-width: 400px;
  z-index: 1000;
  transition: top 0.3s ease;
}

.toast-visible {
  top: 20px;
}

.toast {
  background-color: rgba(0, 0, 0, 0.8);
  color: white;
  padding: 10px 15px;
  border-radius: 4px;
  box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
  text-align: center;
}

/* 动画库引入 */
@import 'https://cdn.jsdelivr.net/npm/animate.css@4.1.1/animate.min.css';
</style>